package com.charon.common.util;
import org.apache.commons.lang3.RandomStringUtils;
import java.security.SecureRandom;
import java.util.Random;
import java.util.UUID;

/**
  *@ClassName: RandomUtils
  *@Description: 随机字符生成工具
  *@Author: Charon [248135724@qq.com]
  *@Date: 2019/1/10 0010 11:59
  *@Version: 1.0
  */
public class RandomUtils {

    private static final int DEFAULT_RANDOM_LENGTH=32;

    /**
     * @Author Charon [248135724@qq.com]
     * @Description Random类中实现的随机算法是伪随机，也就是有规则的随机。在进行随机时，
     * 随机算法的起源数字称为种子数(seed)，在种子数的基础上进行一定的变换，从而产生需要的随机数字。
     * 相同种子数的Random对象，相同次数生成的随机数字是完全相同的。
     * 也就是说，两个种子数相同的Random对象，生成的随机数字完全相同。
     * 所以在需要频繁生成随机数，或者安全要求较高的时候，不要使用Random，因为其生成的值其实是可以预测的。
     * @Date 2019/1/10 0010 12:06
     */
    private static Random rand = new Random();

    /**
     * @Author Charon [248135724@qq.com]
     * @Description SecureRandom是伪随机生成类，和Random不同的是, SecureRandom收集了一些随机事件，
     * 比如鼠标点击，键盘点击等等，SecureRandom 使用这些随机事件作为种子。这意味着，种子是不可预测的，
     * 而不像Random默认使用系统当前时间的毫秒数作为种子，有规律可寻。
     * @Date 2019/1/10 0010 12:08
     */
    private static SecureRandom secureRandom = new SecureRandom();

    /**
      * @Author Charon [248135724@qq.com]
      * @Description 128位的数字，返回值为16进制。
      *     封装JDK自带的UUID, 通过Random数字生成, 中间无-分割。
      * @Date 2019/1/10 0010 12:00
      * @Param []
      * @return java.lang.String
      */
    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * @Author Charon [248135724@qq.com]
     * @Description 使用SecureRandom随机生成Long.
     * @Date 2019/1/10 0010 12:01
     * @Param []
     * @return 随机long
     */
    public static long randomLong() {
        return Math.abs(secureRandom.nextLong());
    }

    /**
      * @Author Charon [248135724@qq.com]
      * @Description 生成10以内的随机数
      * @Date 2019/1/10 0010 12:15
      * @Param []
      * @return int
      */
    public static int randomInt10(){
        return Math.abs(secureRandom.nextInt());
    }

    /**
     * Description: 生成指定位数的随机数，当size小于等于0的时候，返回长度为1的随机数。（例如：size=4，返回1118）
     * <p>Author: Charon [248135724@qq.com]
     * @Date 2019/2/7 2:42
     * @param size 指定位数
     * @return java.lang.String 注意：是字符串格式的。
     */
    public static String randomInt10(int size){
        if(size<=0)size=1;
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<size;i++){
            sb.append(randomInt10());
        }
        return sb.toString();
    }


    /**
      * @Author Charon [248135724@qq.com]
      * @Description 生成100以内的随机数
      * @Date 2019/1/10 0010 12:18
      * @Param []
      * @return int
      */
    public static int randomInt100(){
        return  Math.abs(secureRandom.nextInt(100));//生成0~99的随机数
    }

    /**
      * @author Charon [248135724@qq.com]
      * @description 生成【32位】长度的随机【大小写混合英文数字】字符串
      * @date 2019/1/10 0010 14:23
      * @param
      * @return java.lang.String
      */
    public static String randomString32(){
        return randomString(null);
    }

    /**
      * @Author Charon [248135724@qq.com]
      * @Description 生成指定长度的随机【大小写混合英文数字】字符串
      * @Date 2019/1/10 0010 14:19
      * @Param [length] 指定长度 null:默认32位
      * @return java.lang.String
      */
    public static String randomString(Integer length){
        //默认长度32位
        if(length==null||length==0)length=DEFAULT_RANDOM_LENGTH;
        /**
         * count: 创建一个随机字符串，其长度是指定的字符数,字符将从参数的字母数字字符集中选择
         * letters: true,生成的字符串可以包括字母字符（包含大小写）
         * numbers true,生成的字符串可以包含数字字符
         */
        return RandomStringUtils.random(length, true, true);
    }

    /**
      * @Author Charon [248135724@qq.com]
      * @Description  无数字
      *      生成【32位】的随机【大小写混合英文】字符串
      * @Date 2019/1/10 0010 14:31
      * @Param []
      * @return java.lang.String
      */
    public static String randomLetter32(){
        return randomLetter(null);
    }

    /**
      * @Author Charon [248135724@qq.com]
      * @Description 无数字
      *     生成指定长度的随机【大小写混合英文】字符串
      * @Date 2019/1/10 0010 14:28
      * @Param [length] 指定长度 null:默认32位
      * @return java.lang.String
      */
    public static String randomLetter(Integer length){
        if(length==null||length==0)length=DEFAULT_RANDOM_LENGTH;
        return RandomStringUtils.random(length, true, false);
    }

    /**
      * @Author Charon [248135724@qq.com]
      * @Description 生成随机【大写字母】的【指定长度】字符串
      * @Date 2019/1/10 0010 14:36
      * @Param [length] 指定长度
      * @return java.lang.String
      */
    public static String randomUpperLetter(Integer length){
        return randomLetter(length).toUpperCase();
    }

    /**
     * @Author Charon [248135724@qq.com]
     * @description  生成随机【大写字母】的【32位】字符串
     * @date 2019/1/10 0010 14:36
     * @Param
     * @return java.lang.String
     */
    public static String randomUpperLetter32(){
        return randomLetter32().toUpperCase();
    }

    /**
      * @author Charon [248135724@qq.com]
      * @description 生成指定长度的【纯数字字符串】
      * @date 2019/1/10 0010 14:59
      * @param length 指定长度
      * @return java.lang.String
      */
    public static String randomNumber(Integer length){
        if(length==null||length==0)length=DEFAULT_RANDOM_LENGTH;
        return RandomStringUtils.random(length, false, true);
    }

    /**
      * @author Charon [248135724@qq.com]
      * @description 生成【32位】长度的【纯数字字符串】
      * @date 2019/1/10 0010 15:05
      * @param
      * @return java.lang.String
      */
    public static String randomNumber32(){
        return randomNumber(null);
    }
}
